package com.tlgen.orm.components.autoFill;

import com.tlgen.orm.enums.FillType;

import java.util.Stack;

// ==================== 操作类型上下文 ====================
public class OperationContext {

    // 操作隔离: 每个线程执行时设置自己的操作类型,
    // 风险: 外层调用后进行内层调用会覆盖外层操作类型, 解决方案: 使用操作类型栈
    // 风险: 线程池复用可能导致未清理的上下文, 解决方案: 确保 always clear
    // 风险: 异步任务时, 新线程没有继承操作上下文, 解决方案: 传递上下文
    // 如:
    // FillType currentType = OperationContext.getOperationType();
    //  CompletableFuture.runAsync(() -> {
    //    OperationContext.setOperationType(currentType);
    //    try {
    //        execute(entity, FillType.UPDATE, ...);
    //    } finally {
    //        OperationContext.clear();
    //    }
    // });
    private static final ThreadLocal<Stack<FillType>> operationStack = ThreadLocal.withInitial(Stack::new);

    // 在进入操作时，使用pushOperationType将操作类型压栈
    public static void pushOperationType(FillType type) {
        operationStack.get().push(type);
    }

    // 在操作过程中，使用getOperationType获取当前操作类型（即栈顶元素）
    public static FillType getOperationType() {
        Stack<FillType> stack = operationStack.get();
        return stack.isEmpty() ? null : stack.peek();
    }

    // 在退出操作时，使用popOperationType弹出栈顶元素,
    // 在LifecycleExecutor的finally块中，我们使用popOperationType来弹出操作类型，
    // 而不是清除整个栈（clear）。这样，外层操作的操作类型仍然保留在栈中
    // 完成一个操作层级时恢复上一层操作类型
    public static void popOperationType() {
        Stack<FillType> stack = operationStack.get();
        if (!stack.isEmpty()) {
            stack.pop();
        }
    }

    public static void clear() {
        operationStack.get().clear();
    }

}
